package com.yuxl.common.core.config;


import com.yuxl.common.core.annotation.Anonymous;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.web.server.authorization.AuthorizationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import reactor.core.publisher.Mono;

@Component
public class AnonymousAuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {

    private final RequestMappingHandlerMapping handlerMapping;

    public AnonymousAuthorizationManager(RequestMappingHandlerMapping handlerMapping) {
        this.handlerMapping = handlerMapping;
    }

    @Override
    public Mono<AuthorizationDecision> check(Mono<org.springframework.security.core.Authentication> authentication, AuthorizationContext context) {
        return handlerMapping.getHandler(context.getExchange())
            .flatMap(handler -> {
                if (handler instanceof HandlerMethod handlerMethod) {
                    if (handlerMethod.getBeanType().isAnnotationPresent(Anonymous.class) ||
                        handlerMethod.getMethod().isAnnotationPresent(Anonymous.class)) {
                        return Mono.just(new AuthorizationDecision(true)); // 允许匿名
                    }
                }
                // 没有@Anonymous注解，需要认证
                return authentication.map(auth -> new AuthorizationDecision(auth != null))
                    .defaultIfEmpty(new AuthorizationDecision(false));
            });
    }
}